/*
 *bsp层程序
 *版本v1.3
 *变化点：将bsp层和app层分离
 *时间：2023年10月17日
 *作者：蔡正祥
 */
#include "bsp_Key.h"
#include "bsp_Timer.h"

/****************************************************************************************************************/
/*                              固             定            不             动                                  */
/****************************************************************************************************************/
/*  @brief  创建一个多功能按键
    @param  readPinState
            按键连接的引脚
    @param  *KeyObj
            注册的按键对象
    @return 无
    @property 按键按下后是低电平
*/
void KEY_obj_Activate(uint32_t pin, Key_Function *KeyObj)
{
    if (KeyObj->KEYEnable == 0) // 如果按键是启用的
    {
        return;
    }

    if (pin == KeyObj->KEYTriggerMode && KeyObj->KEYSTATE == longClickLock) // 防止长按多次触发
    {
        KeyObj->KeyPressTimer = 0; // 清空计数
        return;
    }

    if (pin == KeyObj->KEYTriggerMode)
    {
        KeyObj->KeyPressTimer++; // 按键被按下
    }
    else
    {
        KeyObj->KeyCheckCycle++; // 按键没有被按下
        // KeyObj->KEYSTATE = KeyFree; // 给长按解锁
    }

    if (pin == ((KeyObj->KEYTriggerMode + 1) % 2) || KeyObj->KeyPressTimer > KeyObj->KeyLongTimer) // 按键松开 或者 达到了长按时长
    {
        if (KeyObj->KeyPressTimer < 10) // 去波动
        {
            KeyObj->KeyPressTimer = 0; // 清空计数
        }

        if (KeyObj->KeyPressTimer > 10 && KeyObj->KeyPressTimer < 800) // 按键被 点击 了
        {
            KeyObj->KeyPressCount++;   // 被点击次数+1
            KeyObj->KeyPressTimer = 0; // 清空计数
            KeyObj->KeyCheckCycle = 0;
        }

        if (KeyObj->KeyPressTimer >= KeyObj->KeyLongTimer) // 按键被长按
        {
            KeyObj->KEYSTATE = longClick; // 长按
            KeyObj->KeyPressCount = 0;
            KeyObj->KeyPressTimer = 0; // 清空计数
            return;
        }
    }

    if (KeyObj->KeyCheckCycle >= 100) // 240
    {
        switch (KeyObj->KeyPressCount)
        {
        case 1:
            KeyObj->KEYSTATE = oneClick; // 单击
            break;
        case 2:
            KeyObj->KEYSTATE = twoClick; // 双击
            break;
        default:
            KeyObj->KEYSTATE = KeyFree; // 给长按解锁
            break;
        }
        KeyObj->KeyCheckCycle = 0; // 检测周期
        KeyObj->KeyPressCount = 0; // 被按下的次数
    }
}
/*  @brief  按键 单击、双击、长按 事件函数
    @param  *KeyObj
            按键对象
    @return 无
    @property 无
*/
void KEY_obj_event(Key_Function *KeyObj)
{
    if (KeyObj->KEYEnable == 1) // 如果按键是启用的
    {
        switch (KeyObj->KEYSTATE)
        {
        case oneClick:
            KeyObj->KEYEnable = 0; // 防止事件函数长时间处理时定时器一直在++
            KeyObj->KEY_oneClick_event();
            KeyObj->KEYSTATE = KeyFree;
            KeyObj->KEYEnable = 1;
            break;
        case twoClick:
            KeyObj->KEYEnable = 0;
            KeyObj->KEY_twoClick_event();
            KeyObj->KEYSTATE = KeyFree;
            KeyObj->KEYEnable = 1;
            break;
        case longClick:
            KeyObj->KEYEnable = 0;
            KeyObj->KEY_longClick_event();
            KeyObj->KEYSTATE = longClickLock;
            KeyObj->KEYEnable = 1;
            break;
        default:
            break;
        }
    }
}
/*  @brief  设置按键对象的 单击 事件
    @param  *KeyObj
            按键对象
    @param  void (*event)(void)
            按键单击后执行的函数
    @return 无
    @property 无
*/
void KEY_obj_setOneClick_event(Key_Function *KeyObj, void (*event)(void))
{
    KeyObj->KEY_oneClick_event = event;
}
/*  @brief  设置按键对象的 双击 事件
    @param  *KeyObj
            按键对象
    @param  void (*event)(void)
            按键双击后执行的函数
    @return 无
    @property 无
*/
void KEY_obj_setOTwoClick_event(Key_Function *KeyObj, void (*event)(void))
{
    KeyObj->KEY_twoClick_event = event;
}
/*  @brief  设置按键对象的 长按 事件
    @param  *KeyObj
            按键对象
    @param  void (*event)(void)
            按键长按后执行的函数
    @return 无
    @property 无
*/
void KEY_obj_setLongClick_event(Key_Function *KeyObj, void (*event)(void))
{
    KeyObj->KEY_longClick_event = event;
}
/*  @brief  设置按键对象的 长按 时间
    @param  *KeyObj
            按键对象
    @param  time
            时间
    @return 无
    @property 无
*/
void KEY_obj_setLongClick_timer(Key_Function *KeyObj, uint16_t time)
{
    KeyObj->KeyLongTimer = time;
}
/*  @brief  设置按键对象的 状态 可以实现软件方面的点击、双击、长按
    @param  *KeyObj
            按键对象 &+对象名
    @param  sta
            oneClick 单击， twoClick 双击， longClick 长按
    @return 无
    @property 无
*/
void KEY_obj_setState(Key_Function *KeyObj, KeyState sta)
{
    KeyObj->KEYSTATE = sta;
}
/*  @brief  禁用按键
    @param  *KeyObj
            按键对象
    @return 无
    @property 无
*/
void KEY_obj_Disable(Key_Function *KeyObj)
{
    KeyObj->KEYEnable = 0;
}
/*  @brief  启用按键
    @param  *KeyObj
            按键对象
    @return 无
    @property 无
*/
void KEY_obj_Enable(Key_Function *KeyObj)
{
    KeyObj->KEYEnable = 1;
}
/****************************************************************************************************************/
/*                              固             定            不             动                                  */
/****************************************************************************************************************/
